package PolymorphicTest;
/*
多态基础语法
    1.向上转型 向下转型
        java中允许向上转型和向下转型
       子----->父 称为向上转型
       父----->子 称为向下转型
       无论是向下还是向上 两种类型之间必须要有继承关系，没有会报错
    2.什么时候需要向下转型：
        当你需要访问的是子类对象中”特有“的方法。此时必须进行向下转型
    3.instanceof可以在运行阶段动态判断引用指向的对象的类型
      instanceof的语法
        (引用 instanceof 类型)
      instanceof运算符的运算结果只能是：true/false
      c是一个引用，c变量保存了内存地址指向了堆内存中的对象
      假设(c instanceof Cat)为true表示
        c引用指向的堆内存中java对象是一个Cat
      假设(c instanceof Cat)为false表示
        c引用指向的堆内存中java对象不是是一个Cat

 */
public class PolymorphicTest1 {
    public static void main(String[] args ){
        Animal a1 = new Animal();
        Cat c1 = new Cat();
        Bird b1 = new Bird();
        a1.move();  //动物在移动
        c1.move();  //猫在走猫步
        b1.move();  //鸟儿在飞翔
        System.out.println("-----------------------------");
        //根据多态语法，代码可以这样写 向上转型
        Animal c2 = new Cat();   //Animal是父类，Cat是子类，父类型的引用允许指向子类型的对象
        Animal b2 = new Bird();//c2,b2就是父类型的引用，允许a2这个父类型的引用指向子类型的对象
        /*
        什么是多态
        分析c2.move();
         java程序分编译阶段和运行阶段
         编译阶段：
            对于编译器来说，编译器只知道a2的类型是Animal，所以编译器在检查语法的时候，会去Animal.class
            字节码文件中找move()方法，找到了，绑定上move()方法，编译通过，静态绑定成功（编译阶段属于静态绑定）
         运行阶段：
            运行阶段的时候，实际上在堆内存中创建的java对象是Cat对象，所以move的时候，真正参与move的对象是一只猫。
            所以运行阶段会动态执行Cat对象的move()方法，这个过程属于运行阶段绑定（）运行阶段绑定称为动态绑定
         多态表示多种形态：
            编译时一种形态
            运行时另一种形态
         */
        c2.move();
        b2.move();
        System.out.println("--------------------------");

        Animal c3 = new Cat();
        //c3.catchMouse();//这个语句编译不通过 因为编译器只知道c3的类型是Animal，去class文件中找不到
        // catchMouse()方法，静态绑定失败，编译报错，程序无法运行
        //需要向下转型，向下转型有风险，需要instanceof判断
        if(c3 instanceof Cat){
            Cat y = (Cat)c3;
            y.catchMouse();
        }

    }
}
class Animal{
    public void move(){
        System.out.println("动物在移动");
    }
}
class Cat extends Animal{
    public void move(){
        System.out.println("猫在走猫步");
    }
    public void catchMouse(){
        System.out.println("猫在抓老鼠");
        //属于猫的特殊行为
    }
}
class Bird extends Animal{
    public void move(){
        System.out.println("鸟儿在飞翔");
    }
}
